/**
 * 
 */
package de.cbf.cam.dsa.facet.armor;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import de.cbf.cam.dsa.facet.armor.helper.ZoneFactors;
import de.cbf.util.entity.facet.constants.ConstantsFontColorLogView;
import de.cbf.util.entity.facet.entities.FacetOfEntity;
import de.cbf.util.entity.facet.util.TextPartStyled;
import de.cbf.util.uuidheader.entities.UUIDHeader;
import de.cbf.util.uuidheader.exceptions.EntityMergeException;

/**
 * @author Nebelritter
 *
 */
@XmlRootElement(name="armor")
@XmlAccessorType(XmlAccessType.FIELD)
public class FacetArmor extends FacetOfEntity implements FacetArmorConstants {	
	//TODO make zone modifiers editable(with table and "standard" modifiers)
	
	protected int fBeFactor = 20;
	protected int fRsFactor = 20;

	protected Integer	fBe ;
	protected Double	fBeZones ;
	protected Integer	fRsAll ;
	protected Double	fRsAllZones;
	protected Integer	fRsHead;
	protected Integer	fRsChest;
	protected Integer	fRsBack;
	protected Integer	fRsStomach;
	protected Integer	fRsArmLeft;
	protected Integer	fRsArmRight;
	protected Integer	fRsLegLeft;
	protected Integer	fRsLegRight;
	
	protected Double	fZoneDividerRS;
	protected Double 	fZoneDividerBE;
	
	protected Integer	fStars;
	
	protected ZoneFactors fZoneFactors ;
	
	
	public FacetArmor() {
		super();		
	}
	
	/* (non-Javadoc)
	 * @see de.cbf.util.uuidheader.entities.NamedEntity#init()
	 */
	@Override
	protected void init() {	
		super.init();
		fBe				= UNSET_BE;
		fBeZones		= UNSET_BE_ZONES;
		fRsAll			= UNSET_RS_ALL;
		fRsAllZones		= UNSET_RS_ALL_ZONES;
		fRsHead			= UNSET_RS_HEAD;
		fRsChest		= UNSET_RS_CHEST;
		fRsBack			= UNSET_RS_BACK;
		fRsStomach		= UNSET_RS_STOMACH;
		fRsArmLeft		= UNSET_RS_ARM_LEFT;
		fRsArmRight		= UNSET_RS_ARM_RIGHT;
		fRsLegLeft		= UNSET_RS_LEG_LEFT;
		fRsLegRight		= UNSET_RS_LEG_RIGHT;
		fZoneDividerRS	= UNSET_ZONE_DIVIDER_RS;
		fZoneDividerBE	= UNSET_ZONE_DIVIDER_BE;		
		fStars		 	= UNSET_STARS;
		fBeFactor		= UNSET_BE_FACTOR;
		fRsFactor		= UNSET_RS_FACTOR;
		//
		fZoneFactors	= new ZoneFactors(fName);
		fZoneFactors.getPropertyChangeSupport().addPropertyChangeListener(getPclZoneFactors());		
	}	
	/* (non-Javadoc)
	 * @see de.cbf.util.entity.facet.entities.FacetOfEntity#doMergeDataFrom(de.cbf.util.uuidheader.entities.UUIDHeader, boolean)
	 */
	@Override
	protected void doMergeDataFrom(UUIDHeader entity, boolean i_am_older)
			throws EntityMergeException {
		super.doMergeDataFrom(entity, i_am_older);
		if (entity instanceof FacetArmor) {
			FacetArmor other = (FacetArmor) entity;
			if(i_am_older){
				this.fBe = other.fBe;
				this.fBeFactor = other.fBeFactor;
				this.fRsFactor = other.fRsFactor;
				this.fBeZones = other.fBeZones;
				this.fRsAll = other.fRsAll;
				this.fRsAllZones = other.fRsAllZones;
				this.fRsArmLeft = other.fRsArmLeft;
				this.fRsArmRight = other.fRsArmRight;
				this.fRsBack = other.fRsBack;
				this.fRsChest = other.fRsChest;
				this.fRsHead = other.fRsHead;
				this.fRsLegLeft = other.fRsLegLeft;
				this.fRsLegRight = other.fRsLegRight;
				this.fRsStomach = other.fRsStomach;
				this.fStars = other.fStars;
				this.fZoneDividerBE = other.fZoneDividerBE;
				this.fZoneDividerRS = other.fZoneDividerRS;
				this.fZoneFactors.mergeDataFrom(other.fZoneFactors);				
			}
		}else{
			String mergeEntityClass = entity == null? "null":entity.getClass().getName();
			String errorMsg ="EntityToMerge "+mergeEntityClass+" does not fit class:"+this.getClass().getName();
			throw new EntityMergeException(errorMsg);
		}
	}
	@Override
	public List<TextPartStyled> getFacetStyledDescription() {
		List<TextPartStyled> textStyleInfo = new ArrayList<TextPartStyled>();
		
		TextPartStyled textPart;
		//armor heading
		textPart = new TextPartStyled();
		textPart.setText(TEXT_LOG_HEADING_ARMOR+"\n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_FACET);		
		textStyleInfo.add(textPart );
		
		//fBe		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_BE);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fBe value
		textPart = new TextPartStyled();
		textPart.setText(fBe+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fBeZones		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_BE_ZONES);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsAll value
		textPart = new TextPartStyled();
		textPart.setText(fBeZones+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
				
		//fRsAll		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_ALL);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsAll value
		textPart = new TextPartStyled();
		textPart.setText(fRsAll+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );	
		
		//fRsAllZones		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_ALL_ZONES);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsAll value
		textPart = new TextPartStyled();
		textPart.setText(fRsAllZones+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
				
		//fRsHead		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_HEAD);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsHead value
		textPart = new TextPartStyled();
		textPart.setText(fRsHead+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fRsChest		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_CHEST);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsChest value
		textPart = new TextPartStyled();
		textPart.setText(fRsChest+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fRsBack		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_BACK);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsBack value
		textPart = new TextPartStyled();
		textPart.setText(fRsBack+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
				
		//fRsStomach		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_STOMACH);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsStomach value
		textPart = new TextPartStyled();
		textPart.setText(fRsStomach+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fRsArmLeft		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_ARM_LEFT);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsArmLeft value
		textPart = new TextPartStyled();
		textPart.setText(fRsArmLeft+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
				
		//fRsArmRight		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_ARM_RIGHT);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsArmRight value
		textPart = new TextPartStyled();
		textPart.setText(fRsArmRight+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fRsArmLeft		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_LEG_LEFT);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsArmLeft value
		textPart = new TextPartStyled();
		textPart.setText(fRsLegLeft+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
				
		//fRsArmRight		
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_LEG_RIGHT);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsArmRight value
		textPart = new TextPartStyled();
		textPart.setText(fRsLegRight+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fZoneDividerRS	
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_ZONE_DIVIDER_RS);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fZoneDividerRS value
		textPart = new TextPartStyled();
		textPart.setText(fZoneDividerRS+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fZoneDividerBE	
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_ZONE_DIVIDER_BE);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fZoneDividerRS value
		textPart = new TextPartStyled();
		textPart.setText(fZoneDividerBE+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fStars	
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_STARS);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fStars value
		textPart = new TextPartStyled();
		textPart.setText(fStars+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//fBeFactor	
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_BE_FACTOR);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fBeFactor value
		textPart = new TextPartStyled();
		textPart.setText(fBeFactor+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
				
		//fRsFactor	
		textPart = new TextPartStyled();
		textPart.setText("\t"+TEXT_LOG_RS_FACTOR);
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_CATEGORY);		
		textStyleInfo.add(textPart );
		//fRsFactor value
		textPart = new TextPartStyled();
		textPart.setText(fRsFactor+" \n");
		textPart.setStyleConstant(ConstantsFontColorLogView.STYLE_VALUE);		
		textStyleInfo.add(textPart );
		
		//TODO print ZoneFactors
		
		return textStyleInfo;
	}

	/* (non-Javadoc)
	 * @see de.cbf.util.entity.facet.interfaces.IFacetOfEntity#hasUnsetValues()
	 */
	@Override
	public String hasUnsetValues() {
		StringBuffer result = new StringBuffer();
		if(UNSET_BE.equals(fBe)){
			result.append(TEXT_UNSET_BE+"\n");
		}
		if(UNSET_BE_ZONES.equals(fBeZones)){
			result.append(TEXT_UNSET_BE_ZONES+"\n");
		}
		if(UNSET_RS_ALL.equals(fRsAll)){
			result.append(TEXT_UNSET_RS_ALL+"\n");
		}
		if(UNSET_RS_ALL_ZONES.equals(fRsAllZones)){
			result.append(TEXT_UNSET_RS_ALL_ZONES+"\n");
		}
		if(UNSET_RS_HEAD.equals(fRsHead)){
			result.append(TEXT_UNSET_RS_HEAD+"\n");
		}
		if(UNSET_RS_CHEST.equals(fRsChest)){
			result.append(TEXT_UNSET_RS_CHEST+"\n");
		}
		if(UNSET_RS_BACK.equals(fRsBack)){
			result.append(TEXT_UNSET_RS_BACK+"\n");
		}
		if(UNSET_RS_STOMACH.equals(fRsStomach)){
			result.append(TEXT_UNSET_RS_STOMACH+"\n");
		}
		if(UNSET_RS_ARM_LEFT.equals(fRsArmLeft)){
			result.append(TEXT_UNSET_RS_ARM_LEFT+"\n");
		}
		if(UNSET_RS_ARM_RIGHT.equals(fRsArmRight)){
			result.append(TEXT_UNSET_RS_ARM_RIGHT+"\n");
		}
		if(UNSET_RS_LEG_LEFT.equals(fRsLegLeft)){
			result.append(TEXT_UNSET_RS_LEG_LEFT+"\n");
		}
		if(UNSET_RS_LEG_RIGHT.equals(fRsLegRight)){
			result.append(TEXT_UNSET_RS_LEG_RIGHT+"\n");
		}
		if(UNSET_ZONE_DIVIDER_RS.equals(fZoneDividerRS)){
			result.append(TEXT_UNSET_ZONE_DIVIDER_RS+"\n");
		}
		if(UNSET_ZONE_DIVIDER_BE.equals(fZoneDividerBE)){
			result.append(TEXT_UNSET_ZONE_DIVIDER_BE+"\n");
		}
		if(UNSET_STARS.equals(fStars)){
			result.append(TEXT_UNSET_STARS+"\n");
		}
		return result.toString();
	}


	public Integer getBe() {
		return fBe;
	}
	
	public void setBe(Integer newBe) {
		if(newBe == null || newBe.equals(fBe)) return;
		Integer oldBe = this.fBe;
		this.fBe = newBe;
		propertyChangeSupport.fireIndexedPropertyChange(PN_BE, PI_BE,
				oldBe,this.fBe);		
	}
	
	public Double getBeZones() {
		return fBeZones;
	}
	
	public void setBeZones(Double newBeZones) {
		Double oldBeZones = this.fBeZones;
		this.fBeZones = newBeZones;
		propertyChangeSupport.fireIndexedPropertyChange(PN_BE_ZONES, PI_BE_ZONES,oldBeZones,this.fBeZones);		
	}
	
	public Integer getRsAll() {
		return fRsAll;
	}

	public void setRsAll(Integer newRsAll) {
		Integer oldRsAll = this.fRsAll;
		this.fRsAll = newRsAll;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_ALL, PI_RS_ALL,oldRsAll,this.fRsAll);				
	}
	
	public Double getRsAllZones() {
		return fRsAllZones;
	}
	
	public void setRsAllZones(Double newRsAllZones) {
		Double oldRsAllZones = this.fRsAllZones;
		this.fRsAllZones = newRsAllZones;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_ALL_ZONES, PI_RS_ALL_ZONES,oldRsAllZones,this.fRsAllZones);		
	}

	public Integer getRsHead() {
		return fRsHead;
	}
	
	public void setRsHead(Integer newRsHead) {
		Integer oldRsHead = this.fRsHead;
		this.fRsHead = newRsHead;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_HEAD, PI_RS_HEAD,oldRsHead,this.fRsHead);				
	}
	
	public Integer getRsChest() {
		return fRsChest;
	}

	public void setRsChest(Integer newRsChest) {
		Integer oldRsChest = this.fRsChest;
		this.fRsChest = newRsChest;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_CHEST, PI_RS_CHEST,oldRsChest,this.fRsChest);
	}
	
	public Integer getRsBack() {
		return fRsBack;
	}
	
	public void setRsBack(Integer newRsBack) {
		Integer oldRsBack = this.fRsBack;
		this.fRsBack = newRsBack;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_BACK, PI_RS_BACK,oldRsBack,this.fRsBack);	
	}	
	
	public Integer getRsStomach() {
		return fRsStomach;
	}
	
	public void setRsStomach(Integer newRsStomach) {
		Integer oldRsStomach = this.fRsStomach;
		this.fRsStomach = newRsStomach;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_STOMACH, PI_RS_STOMACH,oldRsStomach,this.fRsStomach);	
	}		
	
	public Integer getRsArmLeft() {
		return fRsArmLeft;
	}
	
	public void setRsArmLeft(Integer newRsArmLeft) {
		Integer oldRsArmLeft = this.fRsArmLeft;
		this.fRsArmLeft = newRsArmLeft;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_ARM_LEFT, PI_RS_ARM_LEFT,oldRsArmLeft,this.fRsArmLeft);	
	}	
	
	public Integer getRsArmRight() {
		return fRsArmRight;
	}

	public void setRsArmRight(Integer newRsArmRight) {
		Integer oldRsArmRight = this.fRsArmRight;
		this.fRsArmRight = newRsArmRight;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_ARM_RIGHT, PI_RS_ARM_RIGHT,oldRsArmRight,this.fRsArmRight);	
	}	
	
	public Integer getRsLegLeft() {
		return fRsLegLeft;
	}
	
	public void setRsLegLeft(Integer newRsLegLeft) {
		Integer oldRsLegLeft = this.fRsLegLeft;
		this.fRsLegLeft = newRsLegLeft;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_LEG_LEFT, PI_RS_LEG_LEFT,oldRsLegLeft,this.fRsLegLeft);	
	}
	
	public Integer getRsLegRight() {
		return fRsLegRight;
	}	
	
	public void setRsLegRight(Integer newRsLegRight) {
		Integer oldRsLegRight = this.fRsLegRight;
		this.fRsLegRight = newRsLegRight;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RS_LEG_RIGHT, PI_RS_LEG_RIGHT,oldRsLegRight,this.fRsLegRight);	
	}	
	
	public Double getZoneDividerRS(){
		return fZoneDividerRS;
	}

	public void setZoneDividerRS(Double newZoneDividerRS) {
		if(newZoneDividerRS == null || newZoneDividerRS.equals(fZoneDividerRS)) return;
		Double oldZoneDividerRS = this.fZoneDividerRS;
		this.fZoneDividerRS = newZoneDividerRS;
		propertyChangeSupport.fireIndexedPropertyChange(PN_ZONE_DIVIDER_RS, PI_ZONE_DIVIDER_RS,
				oldZoneDividerRS,this.fZoneDividerRS);	
	}	
	
	public Double getZoneDividerBE(){
		return fZoneDividerBE;
	}

	public void setZoneDividerBE(Double newZoneDividerBE) {
		if(newZoneDividerBE == null || newZoneDividerBE.equals(fZoneDividerBE)) return;
		Double oldZoneDividerBE = this.fZoneDividerBE;
		this.fZoneDividerBE = newZoneDividerBE;
		propertyChangeSupport.fireIndexedPropertyChange(PN_ZONE_DIVIDER_BE, PI_ZONE_DIVIDER_BE,
				oldZoneDividerBE,this.fZoneDividerBE);	
	}	
	
	public Integer getStars(){
		return fStars;
	}

	public void setStars(Integer newStars) {
		if(newStars == null || newStars.equals(fStars)) return;
		Integer oldStars = this.fStars;
		this.fStars = newStars;
		propertyChangeSupport.fireIndexedPropertyChange(PN_STARS, PI_STARS,
				oldStars,this.fStars);	
	}

	public Integer getBeFactor(){
		return fBeFactor;
	}

	public void setBeFactor(Integer newBeFactor) {
		if(newBeFactor == null || newBeFactor.equals(fBeFactor)) return;
		Integer oldBeFactor = this.fBeFactor;
		this.fBeFactor = newBeFactor;
		propertyChangeSupport.fireIndexedPropertyChange(PN_BeFactor, PI_BeFactor, (Object)oldBeFactor, this.fBeFactor);
	}	

	public Integer getRsFactor(){
		return fRsFactor;
	}

	public void setRsFactor(Integer newRsFactor) {
		if(newRsFactor == null || newRsFactor.equals(fRsFactor)) return;
		Integer oldRsFactor = this.fRsFactor;
		this.fRsFactor = newRsFactor;
		propertyChangeSupport.fireIndexedPropertyChange(PN_RsFactor, PI_RsFactor,(Object)oldRsFactor,this.fRsFactor);	
	}	
	
	public ZoneFactors getZoneFactors(){
		return fZoneFactors;
	}	
	
	
	protected PCLZoneFactors pclZoneFactors;
	protected PCLZoneFactors getPclZoneFactors(){
		if(pclZoneFactors == null){
			pclZoneFactors = new PCLZoneFactors();
		}
		return pclZoneFactors;
	}
	protected class PCLZoneFactors implements PropertyChangeListener{

		@Override
		public void propertyChange(PropertyChangeEvent evt) {
			//progress changes
			propertyChangeSupport.firePropertyChange(evt);			
		}		
	}	
}
